// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.erosion.categories;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import zombie.erosion.ErosionData;
import zombie.erosion.ErosionMain;
import zombie.erosion.obj.ErosionObjOverlay;
import zombie.erosion.obj.ErosionObjOverlaySprites;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoObject;
import zombie.iso.IsoWorld;
import zombie.iso.sprite.IsoSprite;
import zombie.iso.sprite.IsoSpriteInstance;

public final class WallVines extends ErosionCategory {
    private ArrayList<ErosionObjOverlay> objs = new ArrayList();
    private static final int DIRNW = 0;
    private static final int DIRN = 1;
    private static final int DIRW = 2;
    private int[][] objsRef = new int[3][2];
    private HashMap<String, Integer> spriteToObj = new HashMap();
    private HashMap<String, Integer> spriteToStage = new HashMap();
    private int[] spawnChance = new int[100];

    @Override
    public boolean replaceExistingObject(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall
    ) {
        int int0 = _sq.getObjects().size();

        for (int int1 = int0 - 1; int1 >= 1; int1--) {
            IsoObject isoObject = _sq.getObjects().get(int1);
            if (isoObject.AttachedAnimSprite != null) {
                for (int int2 = 0; int2 < isoObject.AttachedAnimSprite.size(); int2++) {
                    IsoSprite isoSprite = ((IsoSpriteInstance)isoObject.AttachedAnimSprite.get(int2)).parentSprite;
                    if (isoSprite != null
                        && isoSprite.getName() != null
                        && isoSprite.getName().startsWith("f_wallvines_1_")
                        && this.spriteToObj.containsKey(isoSprite.getName())) {
                        WallVines.CategoryData categoryData = (WallVines.CategoryData)this.setCatModData(_sqErosionData);
                        categoryData.gameObj = (Integer)this.spriteToObj.get(isoSprite.getName());
                        int int3 = (Integer)this.spriteToStage.get(isoSprite.getName());
                        categoryData.stage = int3;
                        categoryData.maxStage = 2;
                        categoryData.spawnTime = 0;
                        isoObject.AttachedAnimSprite.remove(int2);
                        if (isoObject.AttachedAnimSprite != null && int2 < isoObject.AttachedAnimSprite.size()) {
                            isoObject.AttachedAnimSprite.remove(int2);
                        }

                        return true;
                    }
                }
            }
        }

        return false;
    }

    @Override
    public boolean validateSpawn(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall, boolean _isRespawn
    ) {
        if (!_isExterior) {
            return false;
        } else {
            int int0 = _sqErosionData.noiseMainInt;
            int int1 = this.spawnChance[int0];
            if (int1 == 0) {
                return false;
            } else if (_sqErosionData.rand(_sq.x, _sq.y, 101) >= int1) {
                return false;
            } else {
                byte _byte = -1;
                IsoObject isoObject0 = this.validWall(_sq, true, true);
                IsoObject isoObject1 = this.validWall(_sq, false, true);
                if (isoObject0 != null && isoObject1 != null) {
                    _byte = 0;
                } else if (isoObject0 != null) {
                    _byte = 1;
                } else {
                    if (isoObject1 == null) {
                        return false;
                    }

                    _byte = 2;
                }

                WallVines.CategoryData categoryData0 = (WallVines.CategoryData)this.setCatModData(_sqErosionData);
                categoryData0.gameObj = this.objsRef[_byte][_sqErosionData.rand(_sq.x, _sq.y, this.objsRef[_byte].length)];
                categoryData0.maxStage = int0 > 65 ? 3 : (int0 > 60 ? 2 : (int0 > 55 ? 1 : 0));
                categoryData0.stage = 0;
                categoryData0.spawnTime = 100 - int0;
                if (categoryData0.maxStage == 3) {
                    IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare(_sq.getX(), _sq.getY(), _sq.getZ() + 1);
                    if (isoGridSquare != null) {
                        IsoObject isoObject2 = this.validWall(isoGridSquare, _byte == 1, true);
                        ErosionObjOverlay erosionObjOverlay = (ErosionObjOverlay)this.objs.get(categoryData0.gameObj);
                        if (isoObject2 != null && erosionObjOverlay != null) {
                            WallVines.CategoryData categoryData1 = new WallVines.CategoryData();
                            categoryData1.gameObj = this.objsRef[_byte][_sqErosionData.rand(_sq.x, _sq.y, this.objsRef[_byte].length)];
                            categoryData1.maxStage = int0 > 75 ? 2 : (int0 > 70 ? 1 : 0);
                            categoryData1.stage = 0;
                            categoryData1.spawnTime = categoryData0.spawnTime
                                + (int)((float)erosionObjOverlay.cycleTime / ((float)categoryData0.maxStage + 1.0F) * 4.0F);
                            categoryData0.hasTop = categoryData1;
                        } else {
                            categoryData0.maxStage = 2;
                        }
                    } else {
                        categoryData0.maxStage = 2;
                    }
                }

                return true;
            }
        }
    }

    @Override
    public void update(IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionCategory.Data _sqCategoryData, ErosionData.Chunk _chunkData, int _eTick) {
        WallVines.CategoryData categoryData = (WallVines.CategoryData)_sqCategoryData;
        if (_eTick >= categoryData.spawnTime && !categoryData.doNothing) {
            if (categoryData.gameObj >= 0 && categoryData.gameObj < this.objs.size()) {
                ErosionObjOverlay erosionObjOverlay = (ErosionObjOverlay)this.objs.get(categoryData.gameObj);
                int int0 = categoryData.maxStage;
                int int1 = (int)Math.floor((double)((float)(_eTick - categoryData.spawnTime) / ((float)erosionObjOverlay.cycleTime / ((float)int0 + 1.0F))));
                if (int1 < categoryData.stage) {
                    int1 = categoryData.stage;
                }

                if (int1 > int0) {
                    int1 = int0;
                }

                if (int1 > erosionObjOverlay.stages) {
                    int1 = erosionObjOverlay.stages;
                }

                if (int1 == 3 && categoryData.hasTop != null && categoryData.hasTop.spawnTime > _eTick) {
                    int1 = 2;
                }

                int int2 = ErosionMain.getInstance().getSeasons().getSeason();
                if (int1 != categoryData.stage || categoryData.dispSeason != int2) {
                    IsoObject isoObject0 = null;
                    IsoObject isoObject1 = this.validWall(_sq, true, true);
                    IsoObject isoObject2 = this.validWall(_sq, false, true);
                    if (isoObject1 != null && isoObject2 != null) {
                        isoObject0 = isoObject1;
                    } else if (isoObject1 != null) {
                        isoObject0 = isoObject1;
                    } else if (isoObject2 != null) {
                        isoObject0 = isoObject2;
                    }

                    categoryData.dispSeason = int2;
                    if (isoObject0 != null) {
                        int int3 = categoryData.curID;
                        int int4 = erosionObjOverlay.setOverlay(isoObject0, int3, int1, int2, 0.0F);
                        if (int4 >= 0) {
                            categoryData.curID = int4;
                        }
                    } else {
                        categoryData.doNothing = true;
                    }

                    if (int1 == 3 && categoryData.hasTop != null) {
                        IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare(_sq.getX(), _sq.getY(), _sq.getZ() + 1);
                        if (isoGridSquare != null) {
                            this.update(isoGridSquare, _sqErosionData, categoryData.hasTop, _chunkData, _eTick);
                        }
                    }
                }
            } else {
                categoryData.doNothing = true;
            }
        }
    }

    @Override
    public void init() {
        for (int int0 = 0; int0 < 100; int0++) {
            this.spawnChance[int0] = int0 >= 50 ? 100 : 0;
        }

        this.seasonDisp[5].season1 = 5;
        this.seasonDisp[5].season2 = 0;
        this.seasonDisp[5].split = false;
        this.seasonDisp[1].season1 = 1;
        this.seasonDisp[1].season2 = 0;
        this.seasonDisp[1].split = false;
        this.seasonDisp[2].season1 = 2;
        this.seasonDisp[2].season2 = 4;
        this.seasonDisp[2].split = true;
        this.seasonDisp[4].season1 = 4;
        this.seasonDisp[4].season2 = 5;
        this.seasonDisp[4].split = true;
        String string = "f_wallvines_1_";
        int[] int1 = new int[]{5, 2, 4, 1};
        int[] int2 = new int[]{2, 2, 1, 1, 0, 0};
        int[] int3 = new int[3];

        for (int int4 = 0; int4 < int2.length; int4++) {
            ErosionObjOverlaySprites erosionObjOverlaySprites = new ErosionObjOverlaySprites(4, "WallVines");

            for (int int5 = 0; int5 <= 3; int5++) {
                for (int int6 = 0; int6 <= 2; int6++) {
                    int int7 = int6 * 24 + int5 * 6 + int4;
                    erosionObjOverlaySprites.setSprite(int5, string + int7, int1[int6]);
                    if (int6 == 2) {
                        erosionObjOverlaySprites.setSprite(int5, string + int7, int1[int6 + 1]);
                    }

                    this.spriteToObj.put(string + int7, this.objs.size());
                    this.spriteToStage.put(string + int7, int5);
                }
            }

            this.objs.add(new ErosionObjOverlay(erosionObjOverlaySprites, 60, false));
            this.objsRef[int2[int4]][int3[int2[int4]]++] = this.objs.size() - 1;
        }
    }

    @Override
    protected ErosionCategory.Data allocData() {
        return new WallVines.CategoryData();
    }

    @Override
    public void getObjectNames(ArrayList<String> list) {
        for (int _int = 0; _int < this.objs.size(); _int++) {
            if (((ErosionObjOverlay)this.objs.get(_int)).name != null && !list.contains(((ErosionObjOverlay)this.objs.get(_int)).name)) {
                list.add(((ErosionObjOverlay)this.objs.get(_int)).name);
            }
        }
    }

    private static final class CategoryData extends ErosionCategory.Data {
        public int gameObj;
        public int maxStage;
        public int spawnTime;
        public int curID = -999999;
        public WallVines.CategoryData hasTop;

        @Override
        public void save(ByteBuffer byteBuffer) {
            super.save(byteBuffer);
            byteBuffer.put((byte)this.gameObj);
            byteBuffer.put((byte)this.maxStage);
            byteBuffer.putShort((short)this.spawnTime);
            byteBuffer.putInt(this.curID);
            if (this.hasTop != null) {
                byteBuffer.put((byte)1);
                byteBuffer.put((byte)this.hasTop.gameObj);
                byteBuffer.putShort((short)this.hasTop.spawnTime);
                byteBuffer.putInt(this.hasTop.curID);
            } else {
                byteBuffer.put((byte)0);
            }
        }

        @Override
        public void load(ByteBuffer byteBuffer, int _int) {
            super.load(byteBuffer, _int);
            this.gameObj = byteBuffer.get();
            this.maxStage = byteBuffer.get();
            this.spawnTime = byteBuffer.getShort();
            this.curID = byteBuffer.getInt();
            boolean _boolean = byteBuffer.get() == 1;
            if (_boolean) {
                this.hasTop = new WallVines.CategoryData();
                this.hasTop.gameObj = byteBuffer.get();
                this.hasTop.spawnTime = byteBuffer.getShort();
                this.hasTop.curID = byteBuffer.getInt();
            }
        }
    }
}
